home *** CD-ROM | disk | FTP | other *** search
- /*
- * Window Maker window manager
- *
- * Copyright (c) 1997, 1998, 1999 Alfredo K. Kojima
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
- * USA.
- */
-
- #include "wconfig.h"
-
- #include <X11/Xlib.h>
- #include <X11/Xutil.h>
- #include <X11/keysym.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <string.h>
-
- #include "WindowMaker.h"
- #include "wcore.h"
- #include "framewin.h"
- #include "window.h"
- #include "client.h"
- #include "icon.h"
- #include "dock.h"
- #include "funcs.h"
- #include "actions.h"
- #include "workspace.h"
-
- #include "geomview.h"
-
-
- #ifdef KWM_HINTS
- #include "kwm.h"
- #endif
-
- /* How many different types of geometry/position
- display thingies are there? */
- #define NUM_DISPLAYS 4
-
- #define LEFT 1
- #define RIGHT 2
- #define HORIZONTAL (LEFT|RIGHT)
- #define UP 4
- #define DOWN 8
- #define VERTICAL (UP|DOWN)
-
- /****** Global Variables ******/
- extern Time LastTimestamp;
-
- extern Cursor wCursor[WCUR_LAST];
-
- extern WPreferences wPreferences;
-
- extern Atom _XA_WM_PROTOCOLS;
-
-
-
- /*
- *----------------------------------------------------------------------
- * checkMouseSamplingRate-
- * For lowering the mouse motion sampling rate for machines where
- * it's too high (SGIs). If it returns False then the event should be
- * ignored.
- *----------------------------------------------------------------------
- */
- static Bool
- checkMouseSamplingRate(XEvent *ev)
- {
- static Time previousMotion = 0;
-
- if (ev->type == MotionNotify) {
- if (ev->xmotion.time - previousMotion < DELAY_BETWEEN_MOUSE_SAMPLING) {
- return False;
- } else {
- previousMotion = ev->xmotion.time;
- }
- }
- return True;
- }
-
-
-
- /*
- *----------------------------------------------------------------------
- * moveGeometryDisplayCentered
- *
- * routine that moves the geometry/position window on scr so it is
- * centered over the given coordinates (x,y). Also the window position
- * is clamped so it stays on the screen at all times.
- *----------------------------------------------------------------------
- */
- static void
- moveGeometryDisplayCentered(WScreen *scr, int x, int y)
- {
- unsigned int w = WMWidgetWidth(scr->gview);
- unsigned int h = WMWidgetHeight(scr->gview);
-
- x -= w / 2;
- y -= h / 2;
-
- if (x < 1)
- x = 1;
- else if (x > (scr->scr_width - w - 3))
- x = scr->scr_width - w - 3;
-
- if (y < 1)
- y = 1;
- else if (y > (scr->scr_height - h - 3))
- y = scr->scr_height - h - 3;
-
- WMMoveWidget(scr->gview, x, y);
- }
-
-
- static void
- showPosition(WWindow *wwin, int x, int y)
- {
- WScreen *scr = wwin->screen_ptr;
-
- if (wPreferences.move_display == WDIS_NEW) {
- #if 0
- int width = wwin->frame->core->width;
- int height = wwin->frame->core->height;
-
- GC lgc = scr->line_gc;
- XSetForeground(dpy, lgc, scr->line_pixel);
- sprintf(num, "%i", x);
-
- XDrawLine(dpy, scr->root_win, lgc, 0, y-1, scr->scr_width, y-1);
- XDrawLine(dpy, scr->root_win, lgc, 0, y+height+2, scr->scr_width,
- y+height+2);
- XDrawLine(dpy, scr->root_win, lgc, x-1, 0, x-1, scr->scr_height);
- XDrawLine(dpy, scr->root_win, lgc, x+width+2, 0, x+width+2,
- scr->scr_height);
- #endif
- } else {
- WSetGeometryViewShownPosition(scr->gview, x, y);
- }
- }
-
-
- static void
- cyclePositionDisplay(WWindow *wwin, int x, int y, int w, int h)
- {
- WScreen *scr = wwin->screen_ptr;
-
- wPreferences.move_display++;
- wPreferences.move_display %= NUM_DISPLAYS;
-
- if (wPreferences.move_display == WDIS_NEW) {
- WMUnmapWidget(scr->gview);
- } else {
- if (wPreferences.move_display == WDIS_CENTER) {
- moveGeometryDisplayCentered(scr,
- scr->scr_width/2, scr->scr_height/2);
- } else if (wPreferences.move_display == WDIS_TOPLEFT) {
- moveGeometryDisplayCentered(scr, 1, 1);
- } else if (wPreferences.move_display == WDIS_FRAME_CENTER) {
- moveGeometryDisplayCentered(scr, x + w/2, y + h/2);
- }
- WMMapWidget(scr->gview);
- }
- }
-
-
- static void
- mapPositionDisplay(WWindow *wwin, int x, int y, int w, int h)
- {
- WScreen *scr = wwin->screen_ptr;
-
- if (wPreferences.move_display == WDIS_NEW) {
- return;
- } else if (wPreferences.move_display == WDIS_CENTER) {
- moveGeometryDisplayCentered(scr, scr->scr_width / 2,
- scr->scr_height / 2);
- } else if (wPreferences.move_display == WDIS_TOPLEFT) {
- moveGeometryDisplayCentered(scr, 1, 1);
- } else if (wPreferences.move_display == WDIS_FRAME_CENTER) {
- moveGeometryDisplayCentered(scr, x + w/2, y + h/2);
- }
- WMMapWidget(scr->gview);
- WSetGeometryViewShownPosition(scr->gview, x, y);
- }
-
-
- static void
- showGeometry(WWindow *wwin, int x1, int y1, int x2, int y2, int direction)
- {
- WScreen *scr = wwin->screen_ptr;
- Window root = scr->root_win;
- GC gc = scr->line_gc;
- int ty, by, my, x, y, mx, s;
- char num[16];
- XSegment segment[4];
- int fw, fh;
-
- ty = y1 + wwin->frame->top_width;
- by = y2 - wwin->frame->bottom_width;
- fw = WMWidthOfString(scr->info_text_font, "8888", 4);
- fh = WMFontHeight(scr->info_text_font);
-
- if (wPreferences.size_display == WDIS_NEW) {
- XSetForeground(dpy, gc, scr->line_pixel);
-
- /* vertical geometry */
- if (((direction & LEFT) && (x2 < scr->scr_width - fw)) || (x1 < fw)) {
- x = x2;
- s = -15;
- } else {
- x = x1;
- s = 15;
- }
- my = (ty + by) / 2;
-
- /* top arrow */
- /* end bar */
- segment[0].x1 = x - (s + 6); segment[0].y1 = ty;
- segment[0].x2 = x - (s - 10); segment[0].y2 = ty;
-
- /* arrowhead */
- segment[1].x1 = x - (s - 2); segment[1].y1 = ty + 1;
- segment[1].x2 = x - (s - 5); segment[1].y2 = ty + 7;
-
- segment[2].x1 = x - (s - 2); segment[2].y1 = ty + 1;
- segment[2].x2 = x - (s + 1); segment[2].y2 = ty + 7;
-
- /* line */
- segment[3].x1 = x - (s - 2); segment[3].y1 = ty + 1;
- segment[3].x2 = x - (s - 2); segment[3].y2 = my - fh/2 - 1;
-
- XDrawSegments(dpy, root, gc, segment, 4);
-
- /* bottom arrow */
- /* end bar */
- segment[0].y1 = by;
- segment[0].y2 = by;
-
- /* arrowhead */
- segment[1].y1 = by - 1;
- segment[1].y2 = by - 7;
-
- segment[2].y1 = by - 1;
- segment[2].y2 = by - 7;
-
- /* line */
- segment[3].y1 = my + fh/2 + 2;
- segment[3].y2 = by - 1;
-
- XDrawSegments(dpy, root, gc, segment, 4);
-
- sprintf(num, "%i", (by - ty - wwin->normal_hints->base_height) /
- wwin->normal_hints->height_inc);
- fw = WMWidthOfString(scr->info_text_font, num, strlen(num));
-
- /* XSetForeground(dpy, gc, scr->window_title_pixel[WS_UNFOCUSED]); */
-
- /* Display the height. */
- WMDrawString(scr->wmscreen, root, gc, scr->info_text_font,
- x - s + 3 - fw/2, my - fh/2 + 1, num, strlen(num));
- XSetForeground(dpy, gc, scr->line_pixel);
- /* horizontal geometry */
- if (y1 < 15) {
- y = y2;
- s = -15;
- } else {
- y = y1;
- s = 15;
- }
- mx = x1 + (x2 - x1)/2;
- sprintf(num, "%i", (x2 - x1 - wwin->normal_hints->base_width) /
- wwin->normal_hints->width_inc);
- fw = WMWidthOfString(scr->info_text_font, num, strlen(num));
-
- /* left arrow */
- /* end bar */
- segment[0].x1 = x1; segment[0].y1 = y - (s + 6);
- segment[0].x2 = x1; segment[0].y2 = y - (s - 10);
-
- /* arrowhead */
- segment[1].x1 = x1 + 7; segment[1].y1 = y - (s + 1);
- segment[1].x2 = x1 + 1; segment[1].y2 = y - (s - 2);
-
- segment[2].x1 = x1 + 1; segment[2].y1 = y - (s - 2);
- segment[2].x2 = x1 + 7; segment[2].y2 = y - (s - 5);
-
- /* line */
- segment[3].x1 = x1 + 1; segment[3].y1 = y - (s - 2);
- segment[3].x2 = mx - fw/2 - 2; segment[3].y2 = y - (s - 2);
-
- XDrawSegments(dpy, root, gc, segment, 4);
-
- /* right arrow */
- /* end bar */
- segment[0].x1 = x2 + 1;
- segment[0].x2 = x2 + 1;
-
- /* arrowhead */
- segment[1].x1 = x2 - 6;
- segment[1].x2 = x2;
-
- segment[2].x1 = x2;
- segment[2].x2 = x2 - 6;
-
- /* line */
- segment[3].x1 = mx + fw/2 + 2;
- segment[3].x2 = x2;
-
- XDrawSegments(dpy, root, gc, segment, 4);
-
- /* XSetForeground(dpy, gc, scr->window_title_pixel[WS_UNFOCUSED]); */
-
- /* Display the width. */
- WMDrawString(scr->wmscreen, root, gc, scr->info_text_font,
- mx - fw/2 + 1, y - s - fh/2 + 1, num, strlen(num));
- } else {
- WSetGeometryViewShownSize(scr->gview,
- (x2 - x1 - wwin->normal_hints->base_width)
- / wwin->normal_hints->width_inc,
- (by - ty - wwin->normal_hints->base_height)
- / wwin->normal_hints->height_inc);
- }
- }
-
-
- static void
- cycleGeometryDisplay(WWindow *wwin, int x, int y, int w, int h, int dir)
- {
- WScreen *scr = wwin->screen_ptr;
-
- wPreferences.size_display++;
- wPreferences.size_display %= NUM_DISPLAYS;
-
- if (wPreferences.size_display == WDIS_NEW) {
- WMUnmapWidget(scr->gview);
- } else {
- if (wPreferences.size_display == WDIS_CENTER) {
- moveGeometryDisplayCentered(scr,
- scr->scr_width / 2, scr->scr_height / 2);
- } else if (wPreferences.size_display == WDIS_TOPLEFT) {
- moveGeometryDisplayCentered(scr, 1, 1);
- } else if (wPreferences.size_display == WDIS_FRAME_CENTER) {
- moveGeometryDisplayCentered(scr, x + w/2, y + h/2);
- }
- WMMapWidget(scr->gview);
- showGeometry(wwin, x, y, x + w, y + h, dir);
- }
- }
-
-
- static void
- mapGeometryDisplay(WWindow *wwin, int x, int y, int w, int h)
- {
- WScreen *scr = wwin->screen_ptr;
-
- if (wPreferences.size_display == WDIS_NEW)
- return;
-
- if (wPreferences.size_display == WDIS_CENTER) {
- moveGeometryDisplayCentered(scr, scr->scr_width / 2,
- scr->scr_height / 2);
- } else if (wPreferences.size_display == WDIS_TOPLEFT) {
- moveGeometryDisplayCentered(scr, 1, 1);
- } else if (wPreferences.size_display == WDIS_FRAME_CENTER) {
- moveGeometryDisplayCentered(scr, x + w/2, y + h/2);
- }
- WMMapWidget(scr->gview);
- showGeometry(wwin, x, y, x + w, y + h, 0);
- }
-
-
-
- static void
- doWindowMove(WWindow *wwin, WMBag *bag, int dx, int dy)
- {
- WWindow *tmpw;
- int x, y;
- int scr_width = wwin->screen_ptr->scr_width;
- int scr_height = wwin->screen_ptr->scr_height;
-
- if (!bag || !WMGetBagItemCount(bag)) {
- wWindowMove(wwin, wwin->frame_x + dx, wwin->frame_y + dy);
- } else {
- int i;
- for (i = 0; i < WMGetBagItemCount(bag); i++) {
- tmpw = WMGetFromBag(bag, i);
- x = tmpw->frame_x + dx;
- y = tmpw->frame_y + dy;
-
- /* don't let windows become unreachable */
-
- if (x + (int)tmpw->frame->core->width < 20)
- x = 20 - (int)tmpw->frame->core->width;
- else if (x + 20 > scr_width)
- x = scr_width - 20;
-
- if (y + (int)tmpw->frame->core->height < 20)
- y = 20 - (int)tmpw->frame->core->height;
- else if (y + 20 > scr_height)
- y = scr_height - 20;
-
- wWindowMove(tmpw, x, y);
- }
- }
- }
-
-
- static void
- drawTransparentFrame(WWindow *wwin, int x, int y, int width, int height)
- {
- Window root = wwin->screen_ptr->root_win;
- GC gc = wwin->screen_ptr->frame_gc;
- int h = 0;
- int bottom = 0;
-
- if (!WFLAGP(wwin, no_titlebar) && !wwin->flags.shaded) {
- h = WMFontHeight(wwin->screen_ptr->title_font) + (wPreferences.window_title_clearance + TITLEBAR_EXTEND_SPACE) * 2;
- }
- if (!WFLAGP(wwin, no_resizebar) && !wwin->flags.shaded) {
- /* Can't use wwin-frame->bottom_width because, in some cases
- (e.g. interactive placement), frame does not point to anything. */
- bottom = RESIZEBAR_HEIGHT - 1;
- }
- XDrawRectangle(dpy, root, gc, x, y, width + 1, height + 1);
-
- if (h > 0) {
- XDrawLine(dpy, root, gc, x + 1, y + h, x + width + 1, y + h);
- }
- if (bottom > 0) {
- XDrawLine(dpy, root, gc, x + 1,
- y + height - bottom,
- x + width + 1,
- y + height - bottom);
- }
- }
-
-
- static void
- drawFrames(WWindow *wwin, WMBag *bag, int dx, int dy)
- {
- WWindow *tmpw;
- int scr_width = wwin->screen_ptr->scr_width;
- int scr_height = wwin->screen_ptr->scr_height;
- int x, y;
-
- if (!bag) {
-
- x = wwin->frame_x + dx;
- y = wwin->frame_y + dy;
-
- drawTransparentFrame(wwin, x, y,
- wwin->frame->core->width,
- wwin->frame->core->height);
-
- } else {
- int i;
- for (i = 0; i < WMGetBagItemCount(bag); i++) {
- tmpw = WMGetFromBag(bag, i);
- x = tmpw->frame_x + dx;
- y = tmpw->frame_y + dy;
-
- /* don't let windows become unreachable */
-
- if (x + (int)tmpw->frame->core->width < 20)
- x = 20 - (int)tmpw->frame->core->width;
- else if (x + 20 > scr_width)
- x = scr_width - 20;
-
- if (y + (int)tmpw->frame->core->height < 20)
- y = 20 - (int)tmpw->frame->core->height;
- else if (y + 20 > scr_height)
- y = scr_height - 20;
-
- drawTransparentFrame(tmpw, x, y, tmpw->frame->core->width,
- tmpw->frame->core->height);
- }
- }
- }
-
-
-
- static void
- flushMotion()
- {
- XEvent ev;
-
- XSync(dpy, False);
- while (XCheckMaskEvent(dpy, ButtonMotionMask, &ev)) ;
- }
-
-
- static void
- crossWorkspace(WScreen *scr, WWindow *wwin, int opaque_move,
- int new_workspace, int rewind)
- {
- /* do not let window be unmapped */
- if (opaque_move) {
- wwin->flags.changing_workspace = 1;
- wWindowChangeWorkspace(wwin, new_workspace);
- }
- /* go to new workspace */
- wWorkspaceChange(scr, new_workspace);
-
- wwin->flags.changing_workspace = 0;
-
- if (rewind)
- XWarpPointer(dpy, None, None, 0, 0, 0, 0, scr->scr_width - 20, 0);
- else
- XWarpPointer(dpy, None, None, 0, 0, 0, 0, -(scr->scr_width - 20), 0);
-
- flushMotion();
-
- if (!opaque_move) {
- XGrabPointer(dpy, scr->root_win, True, PointerMotionMask
- |ButtonReleaseMask|ButtonPressMask, GrabModeAsync,
- GrabModeAsync, None, wCursor[WCUR_MOVE], CurrentTime);
- }
- }
-
-
-
-
- typedef struct {
- /* arrays of WWindows sorted by the respective border position */
- WWindow **topList; /* top border */
- WWindow **leftList; /* left border */
- WWindow **rightList; /* right border */
- WWindow **bottomList; /* bottom border */
- int count;
-
- /* index of window in the above lists indicating the relative position
- * of the window with the others */
- int topIndex;
- int leftIndex;
- int rightIndex;
- int bottomIndex;
-
- int rubCount; /* for workspace switching */
-
- int winWidth, winHeight; /* width/height of the window */
- int realX, realY; /* actual position of the window */
- int calcX, calcY; /* calculated position of window */
- int omouseX, omouseY; /* old mouse position */
- int mouseX, mouseY; /* last known position of the pointer */
- } MoveData;
-
- #define WTOP(w) (w)->frame_y
- #define WLEFT(w) (w)->frame_x
- #define WRIGHT(w) ((w)->frame_x + (int)(w)->frame->core->width + FRAME_BORDER_WIDTH)
- #define WBOTTOM(w) ((w)->frame_y + (int)(w)->frame->core->height + FRAME_BORDER_WIDTH)
-
- static int
- compareWTop(const void *a, const void *b)
- {
- WWindow *wwin1 = *(WWindow**)a;
- WWindow *wwin2 = *(WWindow**)b;
-
- if (WTOP(wwin1) > WTOP(wwin2))
- return -1;
- else if (WTOP(wwin1) < WTOP(wwin2))
- return 1;
- else
- return 0;
- }
-
-
- static int
- compareWLeft(const void *a, const void *b)
- {
- WWindow *wwin1 = *(WWindow**)a;
- WWindow *wwin2 = *(WWindow**)b;
-
- if (WLEFT(wwin1) > WLEFT(wwin2))
- return -1;
- else if (WLEFT(wwin1) < WLEFT(wwin2))
- return 1;
- else
- return 0;
- }
-
-
- static int
- compareWRight(const void *a, const void *b)
- {
- WWindow *wwin1 = *(WWindow**)a;
- WWindow *wwin2 = *(WWindow**)b;
-
- if (WRIGHT(wwin1) < WRIGHT(wwin2))
- return -1;
- else if (WRIGHT(wwin1) > WRIGHT(wwin2))
- return 1;
- else
- return 0;
- }
-
-
-
- static int
- compareWBottom(const void *a, const void *b)
- {
- WWindow *wwin1 = *(WWindow**)a;
- WWindow *wwin2 = *(WWindow**)b;
-
- if (WBOTTOM(wwin1) < WBOTTOM(wwin2))
- return -1;
- else if (WBOTTOM(wwin1) > WBOTTOM(wwin2))
- return 1;
- else
- return 0;
- }
-
-
- static void
- updateResistance(WWindow *wwin, MoveData *data, int newX, int newY)
- {
- int i;
- int newX2 = newX + data->winWidth;
- int newY2 = newY + data->winHeight;
- Bool ok = False;
-
- if (newX < data->realX) {
- if (data->rightIndex > 0
- && newX < WRIGHT(data->rightList[data->rightIndex-1])) {
- ok = True;
- } else if (data->leftIndex <= data->count-1
- && newX2 <= WLEFT(data->leftList[data->leftIndex])) {
- ok = True;
- }
- } else if (newX > data->realX) {
- if (data->leftIndex > 0
- && newX2 > WLEFT(data->leftList[data->leftIndex-1])) {
- ok = True;
- } else if (data->rightIndex <= data->count-1
- && newX >= WRIGHT(data->rightList[data->rightIndex])) {
- ok = True;
- }
- }
-
- if (!ok) {
- if (newY < data->realY) {
- if (data->bottomIndex > 0
- && newY < WBOTTOM(data->bottomList[data->bottomIndex-1])) {
- ok = True;
- } else if (data->topIndex <= data->count-1
- && newY2 <= WTOP(data->topList[data->topIndex])) {
- ok = True;
- }
- } else if (newY > data->realY) {
- if (data->topIndex > 0
- && newY2 > WTOP(data->topList[data->topIndex-1])) {
- ok = True;
- } else if (data->bottomIndex <= data->count-1
- && newY >= WBOTTOM(data->bottomList[data->bottomIndex])) {
- ok = True;
- }
- }
- }
-
- if (!ok)
- return;
-
- /* TODO: optimize this */
- if (data->realY < WBOTTOM(data->bottomList[0])) {
- data->bottomIndex = 0;
- }
- if (data->realX < WRIGHT(data->rightList[0])) {
- data->rightIndex = 0;
- }
- if ((data->realX + data->winWidth) > WLEFT(data->leftList[0])) {
- data->leftIndex = 0;
- }
- if ((data->realY + data->winHeight) > WTOP(data->topList[0])) {
- data->topIndex = 0;
- }
- for (i = 0; i < data->count; i++) {
- if (data->realY > WBOTTOM(data->bottomList[i])) {
- data->bottomIndex = i + 1;
- }
- if (data->realX > WRIGHT(data->rightList[i])) {
- data->rightIndex = i + 1;
- }
- if ((data->realX + data->winWidth) < WLEFT(data->leftList[i])) {
- data->leftIndex = i + 1;
- }
- if ((data->realY + data->winHeight) < WTOP(data->topList[i])) {
- data->topIndex = i + 1;
- }
- }
- }
-
-
- static void
- freeMoveData(MoveData *data)
- {
- if (data->topList)
- free(data->topList);
- if (data->leftList)
- free(data->leftList);
- if (data->rightList)
- free(data->rightList);
- if (data->bottomList)
- free(data->bottomList);
- }
-
-
- static void
- updateMoveData(WWindow *wwin, MoveData *data)
- {
- WScreen *scr = wwin->screen_ptr;
- WWindow *tmp;
- int i;
-
- data->count = 0;
- tmp = scr->focused_window;
- while (tmp) {
- if (tmp != wwin && scr->current_workspace == tmp->frame->workspace
- && !tmp->flags.miniaturized
- && !tmp->flags.hidden
- && !tmp->flags.obscured
- && !WFLAGP(tmp, sunken)) {
- data->topList[data->count] = tmp;
- data->leftList[data->count] = tmp;
- data->rightList[data->count] = tmp;
- data->bottomList[data->count] = tmp;
- data->count++;
- }
- tmp = tmp->prev;
- }
-
- if (data->count == 0) {
- data->topIndex = 0;
- data->leftIndex = 0;
- data->rightIndex = 0;
- data->bottomIndex = 0;
- return;
- }
-
- /*
- * order from closest to the border of the screen to farthest
- */
- qsort(data->topList, data->count, sizeof(WWindow**), compareWTop);
- qsort(data->leftList, data->count, sizeof(WWindow**), compareWLeft);
- qsort(data->rightList, data->count, sizeof(WWindow**), compareWRight);
- qsort(data->bottomList, data->count, sizeof(WWindow**), compareWBottom);
-
- /* figure the position of the window relative to the others */
-
- data->topIndex = -1;
- data->leftIndex = -1;
- data->rightIndex = -1;
- data->bottomIndex = -1;
-
- if (WTOP(wwin) < WBOTTOM(data->bottomList[0])) {
- data->bottomIndex = 0;
- }
- if (WLEFT(wwin) < WRIGHT(data->rightList[0])) {
- data->rightIndex = 0;
- }
- if (WRIGHT(wwin) > WLEFT(data->leftList[0])) {
- data->leftIndex = 0;
- }
- if (WBOTTOM(wwin) > WTOP(data->topList[0])) {
- data->topIndex = 0;
- }
- for (i = 0; i < data->count; i++) {
- if (WTOP(wwin) >= WBOTTOM(data->bottomList[i])) {
- data->bottomIndex = i + 1;
- }
- if (WLEFT(wwin) >= WRIGHT(data->rightList[i])) {
- data->rightIndex = i + 1;
- }
- if (WRIGHT(wwin) <= WLEFT(data->leftList[i])) {
- data->leftIndex = i + 1;
- }
- if (WBOTTOM(wwin) <= WTOP(data->topList[i])) {
- data->topIndex = i + 1;
- }
- }
- }
-
-
- static void
- initMoveData(WWindow *wwin, MoveData *data)
- {
- int i;
- WWindow *tmp;
-
- memset(data, 0, sizeof(MoveData));
-
- for (i = 0, tmp = wwin->screen_ptr->focused_window;
- tmp != NULL;
- tmp = tmp->prev, i++);
-
- if (i > 1) {
- data->topList = wmalloc(sizeof(WWindow*) * i);
- data->leftList = wmalloc(sizeof(WWindow*) * i);
- data->rightList = wmalloc(sizeof(WWindow*) * i);
- data->bottomList = wmalloc(sizeof(WWindow*) * i);
-
- updateMoveData(wwin, data);
- }
-
- data->realX = wwin->frame_x;
- data->realY = wwin->frame_y;
- data->calcX = wwin->frame_x;
- data->calcY = wwin->frame_y;
-
- data->winWidth = wwin->frame->core->width + 2;
- data->winHeight = wwin->frame->core->height + 2;
- }
-
-
- static Bool
- checkWorkspaceChange(WWindow *wwin, MoveData *data, Bool opaqueMove)
- {
- WScreen *scr = wwin->screen_ptr;
- Bool changed = False;
-
- if (data->mouseX <= 1) {
- if (scr->current_workspace > 0) {
-
- crossWorkspace(scr, wwin, opaqueMove, scr->current_workspace - 1,
- True);
- changed = True;
- data->rubCount = 0;
-
- } else if (scr->current_workspace == 0 && wPreferences.ws_cycle) {
-
- crossWorkspace(scr, wwin, opaqueMove, scr->workspace_count - 1,
- True);
- changed = True;
- data->rubCount = 0;
- }
- } else if (data->mouseX >= scr->scr_width - 2) {
-
- if (scr->current_workspace == scr->workspace_count - 1) {
-
- if (wPreferences.ws_cycle
- || scr->workspace_count == MAX_WORKSPACES) {
-
- crossWorkspace(scr, wwin, opaqueMove, 0, False);
- changed = True;
- data->rubCount = 0;
- }
- /* if user insists on trying to go to next workspace even when
- * it's already the last, create a new one */
- else if (data->omouseX == data->mouseX
- && wPreferences.ws_advance) {
-
- /* detect user "rubbing" the window against the edge */
- if (data->rubCount > 0
- && data->omouseY - data->mouseY > MOVE_THRESHOLD) {
-
- data->rubCount = -(data->rubCount + 1);
-
- } else if (data->rubCount <= 0
- && data->mouseY - data->omouseY > MOVE_THRESHOLD) {
-
- data->rubCount = -data->rubCount + 1;
- }
- }
- /* create a new workspace */
- if (abs(data->rubCount) > 2) {
- /* go to next workspace */
- wWorkspaceNew(scr);
-
- crossWorkspace(scr, wwin, opaqueMove,
- scr->current_workspace+1, False);
- changed = True;
- data->rubCount = 0;
- }
- } else if (scr->current_workspace < scr->workspace_count) {
-
- /* go to next workspace */
- crossWorkspace(scr, wwin, opaqueMove,
- scr->current_workspace+1, False);
- changed = True;
- data->rubCount = 0;
- }
- } else {
- data->rubCount = 0;
- }
-
- return changed;
- }
-
-
- static void
- updateWindowPosition(WWindow *wwin, MoveData *data, Bool doResistance,
- Bool opaqueMove, int newMouseX, int newMouseY)
- {
- WScreen *scr = wwin->screen_ptr;
- int dx, dy; /* how much mouse moved */
- int winL, winR, winT, winB; /* requested new window position */
- int newX, newY; /* actual new window position */
- Bool hresist, vresist;
- Bool updateIndex;
- Bool attract;
-
- hresist = False;
- vresist = False;
-
- updateIndex = False;
-
- /* check the direction of the movement */
- dx = newMouseX - data->mouseX;
- dy = newMouseY - data->mouseY;
-
- data->omouseX = data->mouseX;
- data->omouseY = data->mouseY;
- data->mouseX = newMouseX;
- data->mouseY = newMouseY;
-
- winL = data->calcX + dx;
- winR = data->calcX + data->winWidth + dx;
- winT = data->calcY + dy;
- winB = data->calcY + data->winHeight + dy;
-
- newX = data->realX;
- newY = data->realY;
-
- if (doResistance) {
- int l_edge, r_edge;
- int edge_l, edge_r;
- int t_edge, b_edge;
- int edge_t, edge_b;
- int resist;
-
- resist = WIN_RESISTANCE(wPreferences.edge_resistance);
- attract = wPreferences.attract;
- /* horizontal movement: check horizontal edge resistances */
- if (dx || dy) {
- int i;
- /* window is the leftmost window: check against screen edge */
- l_edge = scr->totalUsableArea.x1;
- r_edge = scr->totalUsableArea.x2 + resist;
- edge_l = scr->totalUsableArea.x1 - resist;
- edge_r = scr->totalUsableArea.x2;
-
- /* 1 */
- if ((data->rightIndex >= 0) && (data->rightIndex <= data->count)) {
- WWindow *looprw;
-
- for (i = data->rightIndex - 1; i >= 0; i--) {
- looprw = data->rightList[i];
- if (!(data->realY > WBOTTOM(looprw)
- || (data->realY + data->winHeight) < WTOP(looprw))) {
- if (attract
- || ((data->realX < (WRIGHT(looprw) + 2)) && dx < 0)) {
- l_edge = WRIGHT(looprw) + 1;
- resist = WIN_RESISTANCE(wPreferences.edge_resistance);
- }
- break;
- }
- }
-
- if (attract) {
- for (i = data->rightIndex; i < data->count; i++) {
- looprw = data->rightList[i];
- if(!(data->realY > WBOTTOM(looprw)
- || (data->realY + data->winHeight) < WTOP(looprw))) {
- r_edge = WRIGHT(looprw) + 1;
- resist = WIN_RESISTANCE(wPreferences.edge_resistance);
- break;
- }
- }
- }
- }
-
- if ((data->leftIndex >= 0) && (data->leftIndex <= data->count)) {
- WWindow *looprw;
-
- for (i = data->leftIndex - 1; i >= 0; i--) {
- looprw = data->leftList[i];
- if (!(data->realY > WBOTTOM(looprw)
- || (data->realY + data->winHeight) < WTOP(looprw))) {
- if (attract
- || (((data->realX + data->winWidth) > (WLEFT(looprw) - 1)) && dx > 0)) {
- edge_r = WLEFT(looprw);
- resist = WIN_RESISTANCE(wPreferences.edge_resistance);
- }
- break;
- }
- }
-
- if (attract)
- for (i = data->leftIndex; i < data->count; i++) {
- looprw = data->leftList[i];
- if(!(data->realY > WBOTTOM(looprw)
- || (data->realY + data->winHeight) < WTOP(looprw))) {
- edge_l = WLEFT(looprw);
- resist = WIN_RESISTANCE(wPreferences.edge_resistance);
- break;
- }
- }
- }
-
- /*
- printf("%d %d\n",winL,winR);
- printf("l_ %d r_ %d _l %d _r %d\n",l_edge,r_edge,edge_l,edge_r);
- */
-
- if ((winL - l_edge) < (r_edge - winL)) {
- if (resist > 0) {
- if ((attract && winL <= l_edge + resist && winL >= l_edge - resist)
- || (dx < 0 && winL <= l_edge && winL >= l_edge - resist)) {
- newX = l_edge;
- hresist = True;
- }
- }
- } else {
- if (resist > 0 && attract && winL >= r_edge - resist && winL <= r_edge + resist) {
- newX = r_edge;
- hresist = True;
- }
- }
-
- if ((winR - edge_l) < (edge_r - winR)) {
- if (resist > 0 && attract && winR <= edge_l + resist && winR >= edge_l - resist) {
- newX = edge_l - data->winWidth;
- hresist = True;
- }
- } else {
- if (resist > 0) {
- if ((attract && winR >= edge_r - resist && winR <= edge_r + resist)
- || (dx > 0 && winR >= edge_r && winR <= edge_r + resist)) {
- newX = edge_r - data->winWidth;
- hresist = True;
- }
- }
- }
-
- /* VeRT */
- t_edge = scr->totalUsableArea.y1;
- b_edge = scr->totalUsableArea.y2 + resist;
- edge_t = scr->totalUsableArea.y1 - resist;
- edge_b = scr->totalUsableArea.y2;
-
- if ((data->bottomIndex >= 0) && (data->bottomIndex <= data->count)) {
- WWindow *looprw;
-
- for (i = data->bottomIndex - 1; i >= 0; i--) {
- looprw = data->bottomList[i];
- if (!(data->realX > WRIGHT(looprw)
- || (data->realX + data->winWidth) < WLEFT(looprw))) {
- if (attract
- || ((data->realY < (WBOTTOM(looprw) + 2)) && dy < 0)) {
- t_edge = WBOTTOM(looprw) + 1;
- resist = WIN_RESISTANCE(wPreferences.edge_resistance);
- }
- break;
- }
- }
-
- if (attract) {
- for (i = data->bottomIndex; i < data->count; i++) {
- looprw = data->bottomList[i];
- if(!(data->realX > WRIGHT(looprw)
- || (data->realX + data->winWidth) < WLEFT(looprw))) {
- b_edge = WBOTTOM(looprw) + 1;
- resist = WIN_RESISTANCE(wPreferences.edge_resistance);
- break;
- }
- }
- }
- }
-
- if ((data->topIndex >= 0) && (data->topIndex <= data->count)) {
- WWindow *looprw;
-
- for (i = data->topIndex - 1; i >= 0; i--) {
- looprw = data->topList[i];
- if (!(data->realX > WRIGHT(looprw)
- || (data->realX + data->winWidth) < WLEFT(looprw))) {
- if (attract
- || (((data->realY + data->winHeight) > (WTOP(looprw) - 1)) && dy > 0)) {
- edge_b = WTOP(looprw);
- resist = WIN_RESISTANCE(wPreferences.edge_resistance);
- }
- break;
- }
- }
-
- if (attract)
- for (i = data->topIndex; i < data->count; i++) {
- looprw = data->topList[i];
- if(!(data->realX > WRIGHT(looprw)
- || (data->realX + data->winWidth) < WLEFT(looprw))) {
- edge_t = WTOP(looprw);
- resist = WIN_RESISTANCE(wPreferences.edge_resistance);
- break;
- }
- }
- }
-
- if ((winT - t_edge) < (b_edge - winT)) {
- if (resist > 0) {
- if ((attract && winT <= t_edge + resist && winT >= t_edge - resist)
- || (dy < 0 && winT <= t_edge && winT >= t_edge - resist)) {
- newY = t_edge;
- vresist = True;
- }
- }
- }
- else {
- if (resist > 0 && attract && winT >= b_edge - resist && winT <= b_edge + resist) {
- newY = b_edge;
- vresist = True;
- }
- }
-
- if ((winB - edge_t) < (edge_b - winB)) {
- if (resist > 0 && attract && winB <= edge_t + resist && winB >= edge_t - resist) {
- newY = edge_t - data->winHeight;
- vresist = True;
- }
- }
- else {
- if (resist > 0) {
- if ((attract && winB >= edge_b - resist && winB <= edge_b + resist)
- || (dy > 0 && winB >= edge_b && winB <= edge_b + resist)) {
- newY = edge_b - data->winHeight;
- vresist = True;
- }
- }
- }
- }
- /* END VeRT */
-
- }
-
- /* update window position */
- data->calcX += dx;
- data->calcY += dy;
-
- if (((dx > 0 && data->calcX - data->realX > 0)
- || (dx < 0 && data->calcX - data->realX < 0)) && !hresist)
- newX = data->calcX;
-
- if (((dy > 0 && data->calcY - data->realY > 0)
- || (dy < 0 && data->calcY - data->realY < 0)) && !vresist)
- newY = data->calcY;
-
- if (data->realX != newX || data->realY != newY) {
-
- if (wPreferences.move_display == WDIS_NEW
- && !scr->selected_windows) {
- showPosition(wwin, data->realX, data->realY);
- }
- if (opaqueMove) {
- doWindowMove(wwin, scr->selected_windows,
- newX - wwin->frame_x,
- newY - wwin->frame_y);
- } else {
- /* erase frames */
- drawFrames(wwin, scr->selected_windows,
- data->realX - wwin->frame_x,
- data->realY - wwin->frame_y);
- }
-
- if (!scr->selected_windows
- && wPreferences.move_display == WDIS_FRAME_CENTER) {
-
- moveGeometryDisplayCentered(scr, newX + data->winWidth/2,
- newY + data->winHeight/2);
- }
-
- if (!opaqueMove) {
- /* draw frames */
- drawFrames(wwin, scr->selected_windows,
- newX - wwin->frame_x,
- newY - wwin->frame_y);
- }
-
- if (!scr->selected_windows) {
- showPosition(wwin, newX, newY);
- }
- }
-
-
- /* recalc relative window position */
- if (doResistance && (data->realX != newX || data->realY != newY)) {
- updateResistance(wwin, data, newX, newY);
- }
-
- data->realX = newX;
- data->realY = newY;
- }
-
-
- #define _KS KEY_CONTROL_WINDOW_WEIGHT
-
- int
- wKeyboardMoveResizeWindow(WWindow *wwin)
- {
- WScreen *scr = wwin->screen_ptr;
- Window root = scr->root_win;
- XEvent event;
- int w = wwin->frame->core->width;
- int h = wwin->frame->core->height;
- int scr_width = wwin->screen_ptr->scr_width;
- int scr_height = wwin->screen_ptr->scr_height;
- int vert_border = wwin->frame->top_width + wwin->frame->bottom_width;
- int src_x = wwin->frame_x;
- int src_y = wwin->frame_y;
- int done,off_x,off_y,ww,wh;
- int kspeed = _KS;
- Time lastTime = 0;
- KeySym keysym=NoSymbol;
- int moment=0;
- KeyCode shiftl,shiftr,ctrll,ctrlmode;
-
- shiftl = XKeysymToKeycode(dpy, XK_Shift_L);
- shiftr = XKeysymToKeycode(dpy, XK_Shift_R);
- ctrll = XKeysymToKeycode(dpy, XK_Control_L);
- ctrlmode=done=off_x=off_y=0;
-
- XSync(dpy, False);
- wusleep(10000);
- XGrabKeyboard(dpy, root, False, GrabModeAsync, GrabModeAsync, CurrentTime);
-
- if (!wwin->flags.selected) {
- wUnselectWindows(scr);
- }
- XGrabServer(dpy);
- XGrabPointer(dpy, scr->root_win, True, PointerMotionMask
- |ButtonReleaseMask|ButtonPressMask, GrabModeAsync,
- GrabModeAsync, None, wCursor[WCUR_DEFAULT], CurrentTime);
-
- if (wwin->flags.shaded || scr->selected_windows) {
- if(scr->selected_windows)
- drawFrames(wwin,scr->selected_windows,off_x,off_y);
- else drawTransparentFrame(wwin, src_x+off_x, src_y+off_y, w, h);
- if(!scr->selected_windows)
- mapPositionDisplay(wwin, src_x, src_y, w, h);
- } else {
- drawTransparentFrame(wwin, src_x+off_x, src_y+off_y, w, h);
- }
- ww=w;
- wh=h;
- while(1) {
- /*
- looper.ox=off_x;
- looper.oy=off_y;
- */
- WMMaskEvent(dpy, KeyPressMask | ButtonReleaseMask
- | ButtonPressMask | ExposureMask, &event);
- if (wwin->flags.shaded || scr->selected_windows) {
- if(scr->selected_windows)
- drawFrames(wwin,scr->selected_windows,off_x,off_y);
- else drawTransparentFrame(wwin, src_x+off_x, src_y+off_y, w, h);
- /*** I HATE EDGE RESISTANCE - ]d ***/
- }
- else {
- drawTransparentFrame(wwin, src_x+off_x, src_y+off_y, ww, wh);
- }
-
- if(ctrlmode)
- showGeometry(wwin, src_x+off_x, src_y+off_y, src_x+off_x+ww, src_y+off_y+wh,0);
-
- XUngrabServer(dpy);
- XSync(dpy, False);
-
- switch (event.type) {
- case KeyPress:
- /* accelerate */
- if (event.xkey.time - lastTime > 50) {
- kspeed/=(1 + (event.xkey.time - lastTime)/100);
- } else {
- if (kspeed < 20) {
- kspeed++;
- }
- }
- if (kspeed < _KS) kspeed = _KS;
- lastTime = event.xkey.time;
-
- if (event.xkey.state & ControlMask && !wwin->flags.shaded) {
- ctrlmode=1;
- wUnselectWindows(scr);
- }
- else {
- ctrlmode=0;
- }
- if (event.xkey.keycode == shiftl || event.xkey.keycode == shiftr) {
- if (ctrlmode)
- cycleGeometryDisplay(wwin, src_x+off_x, src_y+off_y, ww, wh, 0);
- else
- cyclePositionDisplay(wwin, src_x+off_x, src_y+off_y, ww, wh);
- }
- else {
-
- keysym = XLookupKeysym(&event.xkey, 0);
- switch (keysym) {
- case XK_Return:
- done=2;
- break;
- case XK_Escape:
- done=1;
- break;
- case XK_Up:
- case XK_KP_Up:
- case XK_k:
- if (ctrlmode){
- if (moment != UP)
- h = wh;
- h-=kspeed;
- moment = UP;
- if (h < 1) h = 1;
- }
- else off_y-=kspeed;
- break;
- case XK_Down:
- case XK_KP_Down:
- case XK_j:
- if (ctrlmode){
- if (moment != DOWN)
- h = wh;
- h+=kspeed;
- moment = DOWN;
- }
- else off_y+=kspeed;
- break;
- case XK_Left:
- case XK_KP_Left:
- case XK_h:
- if (ctrlmode) {
- if (moment != LEFT)
- w = ww;
- w-=kspeed;
- if (w < 1) w = 1;
- moment = LEFT;
- }
- else off_x-=kspeed;
- break;
- case XK_Right:
- case XK_KP_Right:
- case XK_l:
- if (ctrlmode) {
- if (moment != RIGHT)
- w = ww;
- w+=kspeed;
- moment = RIGHT;
- }
- else off_x+=kspeed;
- break;
- }
-
- ww=w;wh=h;
- wh-=vert_border;
- wWindowConstrainSize(wwin, &ww, &wh);
- wh+=vert_border;
-
- if (wPreferences.ws_cycle){
- if (src_x + off_x + ww < 20){
- if(!scr->current_workspace) {
- wWorkspaceChange(scr, scr->workspace_count-1);
- }
- else wWorkspaceChange(scr, scr->current_workspace-1);
- off_x += scr_width;
- }
- else if (src_x + off_x + 20 > scr_width){
- if(scr->current_workspace == scr->workspace_count-1) {
- wWorkspaceChange(scr, 0);
- }
- else wWorkspaceChange(scr, scr->current_workspace+1);
- off_x -= scr_width;
- }
- }
- else {
- if (src_x + off_x + ww < 20)
- off_x = 20 - ww - src_x;
- else if (src_x + off_x + 20 > scr_width)
- off_x = scr_width - 20 - src_x;
- }
-
- if (src_y + off_y + wh < 20) {
- off_y = 20 - wh - src_y;
- }
- else if (src_y + off_y + 20 > scr_height) {
- off_y = scr_height - 20 - src_y;
- }
- }
- break;
- case ButtonPress:
- case ButtonRelease:
- done=1;
- break;
- default:
- WMHandleEvent(&event);
- break;
- }
-
- XGrabServer(dpy);
- /*xxx*/
-
- if (wwin->flags.shaded && !scr->selected_windows){
- moveGeometryDisplayCentered(scr, src_x+off_x + w/2, src_y+off_y + h/2);
- } else {
- if (ctrlmode) {
- WMUnmapWidget(scr->gview);
- mapGeometryDisplay(wwin, src_x+off_x, src_y+off_y, ww, wh);
- } else if(!scr->selected_windows) {
- WMUnmapWidget(scr->gview);
- mapPositionDisplay(wwin, src_x+off_x, src_y+off_y, ww, wh);
- }
- }
-
- if (wwin->flags.shaded || scr->selected_windows) {
- if (scr->selected_windows)
- drawFrames(wwin,scr->selected_windows,off_x,off_y);
- else
- drawTransparentFrame(wwin, src_x+off_x, src_y+off_y, w, h);
- } else {
- drawTransparentFrame(wwin, src_x+off_x, src_y+off_y, ww, wh);
- }
-
-
- if (ctrlmode) {
- showGeometry(wwin, src_x+off_x, src_y+off_y, src_x+off_x+ww, src_y+off_y+wh,0);
- } else if(!scr->selected_windows)
- showPosition(wwin, src_x+off_x, src_y+off_y);
- /**/
-
- if(done){
- scr->keymove_tick=0;
- /*
- WMDeleteTimerWithClientData(&looper);
- */
- if (wwin->flags.shaded || scr->selected_windows) {
- if(scr->selected_windows)
- drawFrames(wwin,scr->selected_windows,off_x,off_y);
- else drawTransparentFrame(wwin, src_x+off_x, src_y+off_y, w, h);
- }
- else {
- drawTransparentFrame(wwin, src_x+off_x, src_y+off_y, ww, wh);
- }
-
- if (ctrlmode) {
- showGeometry(wwin, src_x+off_x, src_y+off_y, src_x+off_x+ww, src_y+off_y+wh,0);
- WMUnmapWidget(scr->gview);
- } else
- WMUnmapWidget(scr->gview);
-
- XUngrabKeyboard(dpy, CurrentTime);
- XUngrabPointer(dpy, CurrentTime);
- XUngrabServer(dpy);
-
- if(done==2) {
- if (wwin->flags.shaded || scr->selected_windows) {
- if (!scr->selected_windows) {
- wWindowMove(wwin, src_x+off_x, src_y+off_y);
- wWindowSynthConfigureNotify(wwin);
- } else {
- int i;
- WMBag *bag = scr->selected_windows;
- doWindowMove(wwin,scr->selected_windows,off_x,off_y);
- for (i = 0; i < WMGetBagItemCount(bag); i++) {
- wWindowSynthConfigureNotify(WMGetFromBag(bag, i));
- }
- }
- } else {
- if (wwin->client.width != ww)
- wwin->flags.user_changed_width = 1;
-
- if (wwin->client.height != wh - vert_border)
- wwin->flags.user_changed_height = 1;
-
- wWindowConfigure(wwin, src_x+off_x, src_y+off_y,
- ww, wh - vert_border);
- wWindowSynthConfigureNotify(wwin);
- }
- wWindowChangeWorkspace(wwin, scr->current_workspace);
- wSetFocusTo(scr, wwin);
- }
- return 1;
- }
- }
- }
-
-
- /*
- *----------------------------------------------------------------------
- * wMouseMoveWindow--
- * Move the named window and the other selected ones (if any),
- * interactively. Also shows the position of the window, if only one
- * window is being moved.
- * If the window is not on the selected window list, the selected
- * windows are deselected.
- * If shift is pressed during the operation, the position display
- * is changed to another type.
- *
- * Returns:
- * True if the window was moved, False otherwise.
- *
- * Side effects:
- * The window(s) position is changed, and the client(s) are
- * notified about that.
- * The position display configuration may be changed.
- *----------------------------------------------------------------------
- */
- int
- wMouseMoveWindow(WWindow *wwin, XEvent *ev)
- {
- WScreen *scr = wwin->screen_ptr;
- XEvent event;
- Window root = scr->root_win;
- KeyCode shiftl, shiftr;
- Bool done = False;
- int started = 0;
- int warped = 0;
- /* This needs not to change while moving, else bad things can happen */
- int opaqueMove = wPreferences.opaque_move;
- MoveData moveData;
- #ifdef GHOST_WINDOW_MOVE
- RImage *rimg;
-
- rimg = InitGhostWindowMove(scr);
- #endif
-
-
- if (wPreferences.opaque_move && !wPreferences.use_saveunders) {
- XSetWindowAttributes attr;
-
- attr.save_under = True;
- XChangeWindowAttributes(dpy, wwin->frame->core->window,
- CWSaveUnder, &attr);
- }
-
-
- initMoveData(wwin, &moveData);
-
- moveData.mouseX = ev->xmotion.x_root;
- moveData.mouseY = ev->xmotion.y_root;
-
- if (!wwin->flags.selected) {
- /* this window is not selected, unselect others and move only wwin */
- wUnselectWindows(scr);
- }
- #ifdef DEBUG
- puts("Moving window");
- #endif
- shiftl = XKeysymToKeycode(dpy, XK_Shift_L);
- shiftr = XKeysymToKeycode(dpy, XK_Shift_R);
- while (!done) {
- if (warped) {
- int junk;
- Window junkw;
-
- /* XWarpPointer() doesn't seem to generate Motion events, so
- we've got to simulate them */
- XQueryPointer(dpy, root, &junkw, &junkw, &event.xmotion.x_root,
- &event.xmotion.y_root, &junk, &junk,
- (unsigned *) &junk);
- } else {
- WMMaskEvent(dpy, KeyPressMask | ButtonMotionMask
- | PointerMotionHintMask
- | ButtonReleaseMask | ButtonPressMask | ExposureMask,
- &event);
-
- if (event.type == MotionNotify) {
- /* compress MotionNotify events */
- while (XCheckMaskEvent(dpy, ButtonMotionMask, &event)) ;
- if (!checkMouseSamplingRate(&event))
- continue;
- }
- }
- switch (event.type) {
- case KeyPress:
- if ((event.xkey.keycode == shiftl || event.xkey.keycode == shiftr)
- && started && !scr->selected_windows) {
-
- if (!opaqueMove) {
- drawFrames(wwin, scr->selected_windows,
- moveData.realX - wwin->frame_x,
- moveData.realY - wwin->frame_y);
- }
-
- if (wPreferences.move_display == WDIS_NEW
- && !scr->selected_windows) {
- showPosition(wwin, moveData.realX, moveData.realY);
- XUngrabServer(dpy);
- }
- cyclePositionDisplay(wwin, moveData.realX, moveData.realY,
- moveData.winWidth, moveData.winHeight);
-
- if (wPreferences.move_display == WDIS_NEW
- && !scr->selected_windows) {
- XGrabServer(dpy);
- showPosition(wwin, moveData.realX, moveData.realY);
- }
-
- if (!opaqueMove) {
- drawFrames(wwin, scr->selected_windows,
- moveData.realX - wwin->frame_x,
- moveData.realY - wwin->frame_y);
- }
- }
- break;
-
- case MotionNotify:
- if (started) {
- updateWindowPosition(wwin, &moveData,
- scr->selected_windows == NULL
- && wPreferences.edge_resistance > 0,
- opaqueMove,
- event.xmotion.x_root,
- event.xmotion.y_root);
-
- if (!warped && !wPreferences.no_autowrap) {
- int oldWorkspace = scr->current_workspace;
-
- if (wPreferences.move_display == WDIS_NEW
- && !scr->selected_windows) {
- showPosition(wwin, moveData.realX, moveData.realY);
- XUngrabServer(dpy);
- }
- if (!opaqueMove) {
- drawFrames(wwin, scr->selected_windows,
- moveData.realX - wwin->frame_x,
- moveData.realY - wwin->frame_y);
- }
- if (checkWorkspaceChange(wwin, &moveData, opaqueMove)) {
- if (scr->current_workspace != oldWorkspace
- && wPreferences.edge_resistance > 0
- && scr->selected_windows == NULL)
- updateMoveData(wwin, &moveData);
- warped = 1;
- }
- if (!opaqueMove) {
- drawFrames(wwin, scr->selected_windows,
- moveData.realX - wwin->frame_x,
- moveData.realY - wwin->frame_y);
- }
- if (wPreferences.move_display == WDIS_NEW
- && !scr->selected_windows) {
- XSync(dpy, False);
- showPosition(wwin, moveData.realX, moveData.realY);
- XGrabServer(dpy);
- }
- } else {
- warped = 0;
- }
- } else if (abs(ev->xmotion.x_root - event.xmotion.x_root) >= MOVE_THRESHOLD
- || abs(ev->xmotion.y_root - event.xmotion.y_root) >= MOVE_THRESHOLD) {
-
- XChangeActivePointerGrab(dpy, ButtonMotionMask
- | ButtonReleaseMask | ButtonPressMask,
- wCursor[WCUR_MOVE], CurrentTime);
- started = 1;
- XGrabKeyboard(dpy, root, False, GrabModeAsync, GrabModeAsync,
- CurrentTime);
-
- if (!scr->selected_windows)
- mapPositionDisplay(wwin, moveData.realX, moveData.realY,
- moveData.winWidth, moveData.winHeight);
-
- if (started && !opaqueMove)
- drawFrames(wwin, scr->selected_windows, 0, 0);
-
- if (!opaqueMove || (wPreferences.move_display==WDIS_NEW
- && !scr->selected_windows)) {
- XGrabServer(dpy);
- if (wPreferences.move_display==WDIS_NEW)
- showPosition(wwin, moveData.realX, moveData.realY);
- }
- }
- break;
-
- case ButtonPress:
- break;
-
- case ButtonRelease:
- if (event.xbutton.button != ev->xbutton.button)
- break;
-
- if (started) {
- XEvent e;
- if (!opaqueMove) {
- drawFrames(wwin, scr->selected_windows,
- moveData.realX - wwin->frame_x,
- moveData.realY - wwin->frame_y);
- XSync(dpy, 0);
- doWindowMove(wwin, scr->selected_windows,
- moveData.realX - wwin->frame_x,
- moveData.realY - wwin->frame_y);
- }
- #ifndef CONFIGURE_WINDOW_WHILE_MOVING
- wWindowSynthConfigureNotify(wwin);
- #endif
- XUngrabKeyboard(dpy, CurrentTime);
- XUngrabServer(dpy);
- if (!opaqueMove) {
- wWindowChangeWorkspace(wwin, scr->current_workspace);
- wSetFocusTo(scr, wwin);
- }
- if (wPreferences.move_display == WDIS_NEW)
- showPosition(wwin, moveData.realX, moveData.realY);
-
- /* discard all enter/leave events that happened until
- * the time the button was released */
- while (XCheckTypedEvent(dpy, EnterNotify, &e)) {
- if (e.xcrossing.time > event.xbutton.time) {
- XPutBackEvent(dpy, &e);
- break;
- }
- }
- while (XCheckTypedEvent(dpy, LeaveNotify, &e)) {
- if (e.xcrossing.time > event.xbutton.time) {
- XPutBackEvent(dpy, &e);
- break;
- }
- }
-
- if (!scr->selected_windows) {
- /* get rid of the geometry window */
- WMUnmapWidget(scr->gview);
- }
- }
- #ifdef DEBUG
- puts("End move window");
- #endif
- done = True;
- break;
-
- default:
- if (started && !opaqueMove) {
- drawFrames(wwin, scr->selected_windows,
- moveData.realX - wwin->frame_x,
- moveData.realY - wwin->frame_y);
- XUngrabServer(dpy);
- WMHandleEvent(&event);
- XSync(dpy, False);
- XGrabServer(dpy);
- drawFrames(wwin, scr->selected_windows,
- moveData.realX - wwin->frame_x,
- moveData.realY - wwin->frame_y);
- } else {
- WMHandleEvent(&event);
- }
- break;
- }
- }
-
- if (wPreferences.opaque_move && !wPreferences.use_saveunders) {
- XSetWindowAttributes attr;
-
-
- attr.save_under = False;
- XChangeWindowAttributes(dpy, wwin->frame->core->window,
- CWSaveUnder, &attr);
-
- }
-
- freeMoveData(&moveData);
-
- return started;
- }
-
-
- #define RESIZEBAR 1
- #define HCONSTRAIN 2
-
- static int
- getResizeDirection(WWindow *wwin, int x, int y, int dx, int dy,
- int flags)
- {
- int w = wwin->frame->core->width - 1;
- int cw = wwin->frame->resizebar_corner_width;
- int dir;
-
- /* if not resizing through the resizebar */
- if (!(flags & RESIZEBAR)) {
- int xdir = (abs(x) < (wwin->client.width/2)) ? LEFT : RIGHT;
- int ydir = (abs(y) < (wwin->client.height/2)) ? UP : DOWN;
- if (abs(dx) < 2 || abs(dy) < 2) {
- if (abs(dy) > abs(dx))
- xdir = 0;
- else
- ydir = 0;
- }
- return (xdir | ydir);
- }
-
- /* window is too narrow. allow diagonal resize */
- if (cw * 2 >= w) {
- int ydir;
-
- if (flags & HCONSTRAIN)
- ydir = 0;
- else
- ydir = DOWN;
- if (x < cw)
- return (LEFT | ydir);
- else
- return (RIGHT | ydir);
- }
- /* vertical resize */
- if ((x > cw) && (x < w - cw))
- return DOWN;
-
- if (x < cw)
- dir = LEFT;
- else
- dir = RIGHT;
-
- if ((abs(dy) > 0) && !(flags & HCONSTRAIN))
- dir |= DOWN;
-
- return dir;
- }
-
-
- void
- wMouseResizeWindow(WWindow *wwin, XEvent *ev)
- {
- XEvent event;
- WScreen *scr = wwin->screen_ptr;
- Window root = scr->root_win;
- int vert_border = wwin->frame->top_width + wwin->frame->bottom_width;
- int fw = wwin->frame->core->width;
- int fh = wwin->frame->core->height;
- int fx = wwin->frame_x;
- int fy = wwin->frame_y;
- int is_resizebar = (wwin->frame->resizebar
- && ev->xany.window==wwin->frame->resizebar->window);
- int orig_x, orig_y;
- int started;
- int dw, dh;
- int rw = fw, rh = fh;
- int rx1, ry1, rx2, ry2;
- int res = 0;
- KeyCode shiftl, shiftr;
- int h = 0;
- int orig_fx = fx;
- int orig_fy = fy;
- int orig_fw = fw;
- int orig_fh = fh;
-
- if (wwin->flags.shaded) {
- wwarning("internal error: tryein");
- return;
- }
- orig_x = ev->xbutton.x_root;
- orig_y = ev->xbutton.y_root;
-
- started = 0;
- #ifdef DEBUG
- puts("Resizing window");
- #endif
-
- wUnselectWindows(scr);
- rx1 = fx;
- rx2 = fx + fw - 1;
- ry1 = fy;
- ry2 = fy + fh - 1;
- shiftl = XKeysymToKeycode(dpy, XK_Shift_L);
- shiftr = XKeysymToKeycode(dpy, XK_Shift_R);
- if (!WFLAGP(wwin, no_titlebar))
- h = WMFontHeight(wwin->screen_ptr->title_font) + (wPreferences.window_title_clearance + TITLEBAR_EXTEND_SPACE) * 2;
- else
- h = 0;
- while (1) {
- WMMaskEvent(dpy, KeyPressMask | ButtonMotionMask
- | ButtonReleaseMask | PointerMotionHintMask
- | ButtonPressMask | ExposureMask, &event);
- if (!checkMouseSamplingRate(&event))
- continue;
-
- switch (event.type) {
- case KeyPress:
- showGeometry(wwin, fx, fy, fx + fw, fy + fh, res);
- if ((event.xkey.keycode == shiftl || event.xkey.keycode == shiftr)
- && started) {
- drawTransparentFrame(wwin, fx, fy, fw, fh);
- cycleGeometryDisplay(wwin, fx, fy, fw, fh, res);
- drawTransparentFrame(wwin, fx, fy, fw, fh);
- }
- showGeometry(wwin, fx, fy, fx + fw, fy + fh, res);
- break;
-
- case MotionNotify:
- if (started) {
- while (XCheckMaskEvent(dpy, ButtonMotionMask, &event)) ;
-
- dw = 0;
- dh = 0;
-
- orig_fx = fx;
- orig_fy = fy;
- orig_fw = fw;
- orig_fh = fh;
-
- if (res & LEFT)
- dw = orig_x - event.xmotion.x_root;
- else if (res & RIGHT)
- dw = event.xmotion.x_root - orig_x;
- if (res & UP)
- dh = orig_y - event.xmotion.y_root;
- else if (res & DOWN)
- dh = event.xmotion.y_root - orig_y;
-
- orig_x = event.xmotion.x_root;
- orig_y = event.xmotion.y_root;
-
- rw += dw;
- rh += dh;
- fw = rw;
- fh = rh - vert_border;
- wWindowConstrainSize(wwin, &fw, &fh);
- fh += vert_border;
- if (res & LEFT)
- fx = rx2 - fw + 1;
- else if (res & RIGHT)
- fx = rx1;
- if (res & UP)
- fy = ry2 - fh + 1;
- else if (res & DOWN)
- fy = ry1;
- } else if (abs(orig_x - event.xmotion.x_root) >= MOVE_THRESHOLD
- || abs(orig_y - event.xmotion.y_root) >= MOVE_THRESHOLD) {
- int tx, ty;
- Window junkw;
- int flags;
-
- XTranslateCoordinates(dpy, root, wwin->frame->core->window,
- orig_x, orig_y, &tx, &ty, &junkw);
-
- /* check if resizing through resizebar */
- if (is_resizebar)
- flags = RESIZEBAR;
- else
- flags = 0;
-
- if (is_resizebar && ((ev->xbutton.state & ShiftMask)
- || abs(orig_y - event.xmotion.y_root) < HRESIZE_THRESHOLD))
- flags |= HCONSTRAIN;
-
- res = getResizeDirection(wwin, tx, ty,
- orig_x - event.xmotion.x_root,
- orig_y - event.xmotion.y_root, flags);
-
- if (res == (UP|LEFT))
- XChangeActivePointerGrab(dpy, ButtonMotionMask
- | ButtonReleaseMask | ButtonPressMask,
- wCursor[WCUR_TOPLEFTRESIZE], CurrentTime);
- else if (res == (UP|RIGHT))
- XChangeActivePointerGrab(dpy, ButtonMotionMask
- | ButtonReleaseMask | ButtonPressMask,
- wCursor[WCUR_TOPRIGHTRESIZE], CurrentTime);
- else if (res == (DOWN|LEFT))
- XChangeActivePointerGrab(dpy, ButtonMotionMask
- | ButtonReleaseMask | ButtonPressMask,
- wCursor[WCUR_BOTTOMLEFTRESIZE], CurrentTime);
- else if (res == (DOWN|RIGHT))
- XChangeActivePointerGrab(dpy, ButtonMotionMask
- | ButtonReleaseMask | ButtonPressMask,
- wCursor[WCUR_BOTTOMRIGHTRESIZE], CurrentTime);
- else if (res == DOWN || res == UP)
- XChangeActivePointerGrab(dpy, ButtonMotionMask
- | ButtonReleaseMask | ButtonPressMask,
- wCursor[WCUR_VERTICALRESIZE], CurrentTime);
- else if (res & (DOWN|UP))
- XChangeActivePointerGrab(dpy, ButtonMotionMask
- | ButtonReleaseMask | ButtonPressMask,
- wCursor[WCUR_VERTICALRESIZE], CurrentTime);
- else if (res & (LEFT|RIGHT))
- XChangeActivePointerGrab(dpy, ButtonMotionMask
- | ButtonReleaseMask | ButtonPressMask,
- wCursor[WCUR_HORIZONRESIZE], CurrentTime);
-
- XGrabKeyboard(dpy, root, False, GrabModeAsync, GrabModeAsync,
- CurrentTime);
-
- XGrabServer(dpy);
-
- /* Draw the resize frame for the first time. */
- mapGeometryDisplay(wwin, fx, fy, fw, fh);
-
- drawTransparentFrame(wwin, fx, fy, fw, fh);
-
- showGeometry(wwin, fx, fy, fx + fw, fy + fh, res);
-
- started = 1;
- }
- if (started) {
- if (wPreferences.size_display == WDIS_FRAME_CENTER) {
- drawTransparentFrame(wwin, orig_fx, orig_fy,
- orig_fw, orig_fh);
- moveGeometryDisplayCentered(scr, fx + fw / 2, fy + fh / 2);
- drawTransparentFrame(wwin, fx, fy, fw, fh);
- } else {
- drawTransparentFrame(wwin, orig_fx, orig_fy,
- orig_fw, orig_fh);
- drawTransparentFrame(wwin, fx, fy, fw, fh);
- }
- if (fh != orig_fh || fw != orig_fw) {
- if (wPreferences.size_display == WDIS_NEW) {
- showGeometry(wwin, orig_fx, orig_fy, orig_fx + orig_fw,
- orig_fy + orig_fh, res);
- }
- showGeometry(wwin, fx, fy, fx + fw, fy + fh, res);
- }
- }
- break;
-
- case ButtonPress:
- break;
-
- case ButtonRelease:
- if (event.xbutton.button != ev->xbutton.button)
- break;
-
- if (started) {
- showGeometry(wwin, fx, fy, fx + fw, fy + fh, res);
-
- drawTransparentFrame(wwin, fx, fy, fw, fh);
-
- XUngrabKeyboard(dpy, CurrentTime);
- WMUnmapWidget(scr->gview);
- XUngrabServer(dpy);
-
- if (wwin->client.width != fw)
- wwin->flags.user_changed_width = 1;
-
- if (wwin->client.height != fh - vert_border)
- wwin->flags.user_changed_height = 1;
-
- wWindowConfigure(wwin, fx, fy, fw, fh - vert_border);
- }
- #ifdef DEBUG
- puts("End resize window");
- #endif
- return;
-
- default:
- WMHandleEvent(&event);
- }
- }
- }
-
- #undef LEFT
- #undef RIGHT
- #undef HORIZONTAL
- #undef UP
- #undef DOWN
- #undef VERTICAL
- #undef HCONSTRAIN
- #undef RESIZEBAR
-
- void
- wUnselectWindows(WScreen *scr)
- {
- WWindow *wwin;
-
- if (!scr->selected_windows)
- return;
-
- while (WMGetBagItemCount(scr->selected_windows)) {
- WMBagIterator dummy;
-
- wwin = WMBagFirst(scr->selected_windows, &dummy);
- if (wwin->flags.miniaturized && wwin->icon && wwin->icon->selected)
- wIconSelect(wwin->icon);
-
- wSelectWindow(wwin, False);
- }
- WMFreeBag(scr->selected_windows);
- scr->selected_windows = NULL;
- }
-
- #ifndef LITE
- static void
- selectWindowsInside(WScreen *scr, int x1, int y1, int x2, int y2)
- {
- WWindow *tmpw;
-
- /* select the windows and put them in the selected window list */
- tmpw = scr->focused_window;
- while (tmpw != NULL) {
- if (!(tmpw->flags.miniaturized || tmpw->flags.hidden)) {
- if ((tmpw->frame->workspace == scr->current_workspace
- || IS_OMNIPRESENT(tmpw))
- && (tmpw->frame_x >= x1) && (tmpw->frame_y >= y1)
- && (tmpw->frame->core->width + tmpw->frame_x <= x2)
- && (tmpw->frame->core->height + tmpw->frame_y <= y2)) {
- wSelectWindow(tmpw, True);
- }
- }
- tmpw = tmpw->prev;
- }
- }
-
-
- void
- wSelectWindows(WScreen *scr, XEvent *ev)
- {
- XEvent event;
- Window root = scr->root_win;
- GC gc = scr->frame_gc;
- int xp = ev->xbutton.x_root;
- int yp = ev->xbutton.y_root;
- int w = 0, h = 0;
- int x = xp, y = yp;
-
- #ifdef DEBUG
- puts("Selecting windows");
- #endif
- if (XGrabPointer(dpy, scr->root_win, False, ButtonMotionMask
- | ButtonReleaseMask | ButtonPressMask, GrabModeAsync,
- GrabModeAsync, None, wCursor[WCUR_DEFAULT],
- CurrentTime) != Success) {
- return;
- }
- XGrabServer(dpy);
-
- wUnselectWindows(scr);
-
- XDrawRectangle(dpy, root, gc, xp, yp, w, h);
- while (1) {
- WMMaskEvent(dpy, ButtonReleaseMask | PointerMotionMask
- | ButtonPressMask, &event);
-
- switch (event.type) {
- case MotionNotify:
- XDrawRectangle(dpy, root, gc, x, y, w, h);
- x = event.xmotion.x_root;
- if (x < xp) {
- w = xp - x;
- } else {
- w = x - xp;
- x = xp;
- }
- y = event.xmotion.y_root;
- if (y < yp) {
- h = yp - y;
- } else {
- h = y - yp;
- y = yp;
- }
- XDrawRectangle(dpy, root, gc, x, y, w, h);
- break;
-
- case ButtonPress:
- break;
-
- case ButtonRelease:
- if (event.xbutton.button != ev->xbutton.button)
- break;
-
- XDrawRectangle(dpy, root, gc, x, y, w, h);
- XUngrabServer(dpy);
- XUngrabPointer(dpy, CurrentTime);
- selectWindowsInside(scr, x, y, x + w, y + h);
-
- #ifdef KWM_HINTS
- wKWMSelectRootRegion(scr, xp, yp, w, h,
- event.xbutton.state & ControlMask);
- #endif /* KWM_HINTS */
-
- #ifdef DEBUG
- puts("End window selection");
- #endif
- return;
-
- default:
- WMHandleEvent(&event);
- break;
- }
- }
- }
- #endif /* !LITE */
-
- void
- InteractivePlaceWindow(WWindow *wwin, int *x_ret, int *y_ret,
- unsigned width, unsigned height)
- {
- WScreen *scr = wwin->screen_ptr;
- Window root = scr->root_win;
- int x, y, h = 0;
- XEvent event;
- KeyCode shiftl, shiftr;
- Window junkw;
- int junk;
-
- if (XGrabPointer(dpy, root, True, PointerMotionMask | ButtonPressMask,
- GrabModeAsync, GrabModeAsync, None,
- wCursor[WCUR_DEFAULT], CurrentTime) != Success) {
- *x_ret = 0;
- *y_ret = 0;
- return;
- }
- if (!WFLAGP(wwin, no_titlebar)) {
- h = WMFontHeight(scr->title_font) + (wPreferences.window_title_clearance + TITLEBAR_EXTEND_SPACE) * 2;
- height += h;
- }
- if (!WFLAGP(wwin, no_resizebar)) {
- height += RESIZEBAR_HEIGHT;
- }
- XGrabKeyboard(dpy, root, False, GrabModeAsync, GrabModeAsync, CurrentTime);
- XQueryPointer(dpy, root, &junkw, &junkw, &x, &y, &junk, &junk,
- (unsigned *) &junk);
- mapPositionDisplay(wwin, x - width/2, y - h/2, width, height);
-
- drawTransparentFrame(wwin, x - width/2, y - h/2, width, height);
-
- shiftl = XKeysymToKeycode(dpy, XK_Shift_L);
- shiftr = XKeysymToKeycode(dpy, XK_Shift_R);
- while (1) {
- WMMaskEvent(dpy, PointerMotionMask|ButtonPressMask|ExposureMask|KeyPressMask,
- &event);
-
- if (!checkMouseSamplingRate(&event))
- continue;
-
- switch (event.type) {
- case KeyPress:
- if ((event.xkey.keycode == shiftl)
- || (event.xkey.keycode == shiftr)) {
- drawTransparentFrame(wwin,
- x - width/2, y - h/2, width, height);
- cyclePositionDisplay(wwin,
- x - width/2, y - h/2, width, height);
- drawTransparentFrame(wwin,
- x - width/2, y - h/2, width, height);
- }
- break;
-
- case MotionNotify:
- drawTransparentFrame(wwin, x - width/2, y - h/2, width, height);
-
- x = event.xmotion.x_root;
- y = event.xmotion.y_root;
-
- if (wPreferences.move_display == WDIS_FRAME_CENTER)
- moveGeometryDisplayCentered(scr, x, y + (height - h) / 2);
-
- showPosition(wwin, x - width/2, y - h/2);
-
- drawTransparentFrame(wwin, x - width/2, y - h/2, width, height);
-
- break;
-
- case ButtonPress:
- drawTransparentFrame(wwin, x - width/2, y - h/2, width, height);
- XSync(dpy, 0);
- *x_ret = x - width/2;
- *y_ret = y - h/2;
- XUngrabPointer(dpy, CurrentTime);
- XUngrabKeyboard(dpy, CurrentTime);
- /* get rid of the geometry window */
- WMUnmapWidget(scr->gview);
- return;
-
- default:
- WMHandleEvent(&event);
- break;
- }
- }
- }
-